{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "axgaosQDxyM4"
      },
      "source": [
        "# How To Build An AI Agent With OpenAI, LlamaIndex and MongoDB"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ECTvK2pW84vN"
      },
      "source": [
        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/mongodb-developer/GenAI-Showcase/blob/main/notebooks/agents/airbnb_agent_openai_llamaindex_mongodb.ipynb)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "l7PuZzJDwAWr"
      },
      "source": [
        "## Install Libraries"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "jwCBOcXw_nBh",
        "outputId": "bb9e4031-5d5c-4b4a-98e3-ff729f6086c7"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/1.6 MB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m51.8 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m28.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m32.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.5/1.5 MB\u001b[0m \u001b[31m36.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m176.8/176.8 kB\u001b[0m \u001b[31m8.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m295.8/295.8 kB\u001b[0m \u001b[31m12.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m38.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.5/49.5 kB\u001b[0m \u001b[31m2.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.4/1.4 MB\u001b[0m \u001b[31m21.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m313.6/313.6 kB\u001b[0m \u001b[31m12.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m89.9/89.9 kB\u001b[0m \u001b[31m3.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.1/13.1 MB\u001b[0m \u001b[31m67.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m480.6/480.6 kB\u001b[0m \u001b[31m24.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m116.3/116.3 kB\u001b[0m \u001b[31m6.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m179.3/179.3 kB\u001b[0m \u001b[31m10.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m134.8/134.8 kB\u001b[0m \u001b[31m8.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m194.1/194.1 kB\u001b[0m \u001b[31m11.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
            "cudf-cu12 24.10.1 requires pandas<2.2.3dev0,>=2.0, but you have pandas 2.2.3 which is incompatible.\n",
            "gcsfs 2024.10.0 requires fsspec==2024.10.0, but you have fsspec 2024.9.0 which is incompatible.\n",
            "google-colab 1.0.0 requires pandas==2.2.2, but you have pandas 2.2.3 which is incompatible.\u001b[0m\u001b[31m\n",
            "\u001b[0m"
          ]
        }
      ],
      "source": [
        "!pip install -qU llama-index  # main llamaindex libary\n",
        "!pip install -qU llama-index-vector-stores-mongodb # mongodb vector database\n",
        "!pip install -qU llama-index-llms-openai # openai llm provider\n",
        "!pip install -qU llama-index-embeddings-openai # openai embedding provider\n",
        "!pip install -qU pymongo pandas datasets # others"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "siDlNHlKwGgE"
      },
      "source": [
        "## Setup Prerequisites"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {
        "id": "3v6adnzJ9INt"
      },
      "outputs": [],
      "source": [
        "import getpass\n",
        "import os\n",
        "\n",
        "from pymongo import MongoClient"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "2sxMs_60wNPD",
        "outputId": "5bf5d12a-8b65-424f-cd7d-b6ac6051e830"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Enter OpenAI API Key:··········\n"
          ]
        }
      ],
      "source": [
        "os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter OpenAI API Key:\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "2cNHYOBGKDTd",
        "outputId": "9a206804-d634-4aa6-c1a8-22c1fd842b6d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Enter your MongoDB URI: ··········\n"
          ]
        }
      ],
      "source": [
        "MONGODB_URI = getpass.getpass(\"Enter your MongoDB URI: \")\n",
        "mongodb_client = MongoClient(\n",
        "    MONGODB_URI, appname=\"devrel.content.airbnb_agent_mongodb_llamaindex\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "osmgS5DbxD7h"
      },
      "source": [
        "## Configure LLMs and Embedding Models"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 53,
      "metadata": {
        "id": "qz0tqiaswbKW"
      },
      "outputs": [],
      "source": [
        "from llama_index.core import Settings\n",
        "from llama_index.embeddings.openai import OpenAIEmbedding\n",
        "from llama_index.llms.openai import OpenAI\n",
        "\n",
        "Settings.embed_model = OpenAIEmbedding(\n",
        "    model=\"text-embedding-3-small\",\n",
        "    dimensions=256,\n",
        "    embed_batch_size=10,\n",
        "    openai_api_key=os.environ[\"OPENAI_API_KEY\"],\n",
        ")\n",
        "llm = OpenAI(model=\"gpt-4o\", temperature=0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OwX4bbG2xeHG"
      },
      "source": [
        "## Download the Dataset"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 29,
      "metadata": {
        "id": "1MWkFKGy__ut"
      },
      "outputs": [],
      "source": [
        "import pandas as pd\n",
        "from datasets import load_dataset\n",
        "\n",
        "# https://huggingface.co/datasets/MongoDB/airbnb_embeddings\n",
        "data = load_dataset(\"MongoDB/airbnb_embeddings\", split=\"train\", streaming=True)\n",
        "data = data.take(200)\n",
        "\n",
        "# Convert the dataset to a pandas dataframe\n",
        "data_df = pd.DataFrame(data)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 30,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 759
        },
        "id": "6VZLQgaHI0VD",
        "outputId": "1f86ddd5-e9f6-417f-905b-fbc953a87d15"
      },
      "outputs": [
        {
          "data": {
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "dataframe",
              "variable_name": "data_df"
            },
            "text/html": [
              "\n",
              "  <div id=\"df-4b3fa277-0477-41c7-8196-d88c7b195e03\" class=\"colab-df-container\">\n",
              "    <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>_id</th>\n",
              "      <th>listing_url</th>\n",
              "      <th>name</th>\n",
              "      <th>summary</th>\n",
              "      <th>space</th>\n",
              "      <th>description</th>\n",
              "      <th>neighborhood_overview</th>\n",
              "      <th>notes</th>\n",
              "      <th>transit</th>\n",
              "      <th>access</th>\n",
              "      <th>...</th>\n",
              "      <th>images</th>\n",
              "      <th>host</th>\n",
              "      <th>address</th>\n",
              "      <th>availability</th>\n",
              "      <th>review_scores</th>\n",
              "      <th>reviews</th>\n",
              "      <th>weekly_price</th>\n",
              "      <th>monthly_price</th>\n",
              "      <th>text_embeddings</th>\n",
              "      <th>image_embeddings</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>10006546</td>\n",
              "      <td>https://www.airbnb.com/rooms/10006546</td>\n",
              "      <td>Ribeira Charming Duplex</td>\n",
              "      <td>Fantastic duplex apartment with three bedrooms...</td>\n",
              "      <td>Privileged views of the Douro River and Ribeir...</td>\n",
              "      <td>Fantastic duplex apartment with three bedrooms...</td>\n",
              "      <td>In the neighborhood of the river, you can find...</td>\n",
              "      <td>Lose yourself in the narrow streets and stairc...</td>\n",
              "      <td>Transport: • Metro station and S. Bento railwa...</td>\n",
              "      <td>We are always available to help guests. The ho...</td>\n",
              "      <td>...</td>\n",
              "      <td>{'thumbnail_url': '', 'medium_url': '', 'pictu...</td>\n",
              "      <td>{'host_id': '51399391', 'host_url': 'https://w...</td>\n",
              "      <td>{'street': 'Porto, Porto, Portugal', 'suburb':...</td>\n",
              "      <td>{'availability_30': 28, 'availability_60': 47,...</td>\n",
              "      <td>{'review_scores_accuracy': 9, 'review_scores_c...</td>\n",
              "      <td>[{'_id': '58663741', 'date': 2016-01-03 05:00:...</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>[0.0123710884, -0.0180913936, -0.016843712, -0...</td>\n",
              "      <td>[-0.1302358955, 0.1534578055, 0.0199299306, -0...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>10021707</td>\n",
              "      <td>https://www.airbnb.com/rooms/10021707</td>\n",
              "      <td>Private Room in Bushwick</td>\n",
              "      <td>Here exists a very cozy room for rent in a sha...</td>\n",
              "      <td></td>\n",
              "      <td>Here exists a very cozy room for rent in a sha...</td>\n",
              "      <td></td>\n",
              "      <td></td>\n",
              "      <td></td>\n",
              "      <td></td>\n",
              "      <td>...</td>\n",
              "      <td>{'thumbnail_url': '', 'medium_url': '', 'pictu...</td>\n",
              "      <td>{'host_id': '11275734', 'host_url': 'https://w...</td>\n",
              "      <td>{'street': 'Brooklyn, NY, United States', 'sub...</td>\n",
              "      <td>{'availability_30': 0, 'availability_60': 0, '...</td>\n",
              "      <td>{'review_scores_accuracy': 10, 'review_scores_...</td>\n",
              "      <td>[{'_id': '61050713', 'date': 2016-01-31 05:00:...</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>[0.0153845912, -0.0348115042, -0.0093448907, 0...</td>\n",
              "      <td>[0.0340401195, 0.1742489338, -0.1572628617, 0....</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>1001265</td>\n",
              "      <td>https://www.airbnb.com/rooms/1001265</td>\n",
              "      <td>Ocean View Waikiki Marina w/prkg</td>\n",
              "      <td>A short distance from Honolulu's billion dolla...</td>\n",
              "      <td>Great studio located on Ala Moana across the s...</td>\n",
              "      <td>A short distance from Honolulu's billion dolla...</td>\n",
              "      <td>You can breath ocean as well as aloha.</td>\n",
              "      <td></td>\n",
              "      <td>Honolulu does have a very good air conditioned...</td>\n",
              "      <td>Pool, hot tub and tennis</td>\n",
              "      <td>...</td>\n",
              "      <td>{'thumbnail_url': '', 'medium_url': '', 'pictu...</td>\n",
              "      <td>{'host_id': '5448114', 'host_url': 'https://ww...</td>\n",
              "      <td>{'street': 'Honolulu, HI, United States', 'sub...</td>\n",
              "      <td>{'availability_30': 16, 'availability_60': 46,...</td>\n",
              "      <td>{'review_scores_accuracy': 9, 'review_scores_c...</td>\n",
              "      <td>[{'_id': '4765259', 'date': 2013-05-24 04:00:0...</td>\n",
              "      <td>650.0</td>\n",
              "      <td>2150.0</td>\n",
              "      <td>[-0.0400562622, -0.0405789167, 0.000644172, 0....</td>\n",
              "      <td>[-0.1640156209, 0.1256971657, 0.6594450474, -0...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>10009999</td>\n",
              "      <td>https://www.airbnb.com/rooms/10009999</td>\n",
              "      <td>Horto flat with small garden</td>\n",
              "      <td>One bedroom + sofa-bed in quiet and bucolic ne...</td>\n",
              "      <td>Lovely one bedroom + sofa-bed in the living ro...</td>\n",
              "      <td>One bedroom + sofa-bed in quiet and bucolic ne...</td>\n",
              "      <td>This charming ground floor flat is located in ...</td>\n",
              "      <td>There´s a table in the living room now, that d...</td>\n",
              "      <td>Easy access to transport (bus, taxi, car) and ...</td>\n",
              "      <td></td>\n",
              "      <td>...</td>\n",
              "      <td>{'thumbnail_url': '', 'medium_url': '', 'pictu...</td>\n",
              "      <td>{'host_id': '1282196', 'host_url': 'https://ww...</td>\n",
              "      <td>{'street': 'Rio de Janeiro, Rio de Janeiro, Br...</td>\n",
              "      <td>{'availability_30': 0, 'availability_60': 0, '...</td>\n",
              "      <td>{'review_scores_accuracy': None, 'review_score...</td>\n",
              "      <td>[]</td>\n",
              "      <td>1492.0</td>\n",
              "      <td>4849.0</td>\n",
              "      <td>[-0.063234821, 0.0017937823, -0.0243996996, -0...</td>\n",
              "      <td>[-0.1292964518, 0.037789464, 0.2443587631, 0.0...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>10047964</td>\n",
              "      <td>https://www.airbnb.com/rooms/10047964</td>\n",
              "      <td>Charming Flat in Downtown Moda</td>\n",
              "      <td>Fully furnished 3+1 flat decorated with vintag...</td>\n",
              "      <td>The apartment is composed of 1 big bedroom wit...</td>\n",
              "      <td>Fully furnished 3+1 flat decorated with vintag...</td>\n",
              "      <td>With its diversity Moda- Kadikoy is one of the...</td>\n",
              "      <td></td>\n",
              "      <td></td>\n",
              "      <td></td>\n",
              "      <td>...</td>\n",
              "      <td>{'thumbnail_url': '', 'medium_url': '', 'pictu...</td>\n",
              "      <td>{'host_id': '1241644', 'host_url': 'https://ww...</td>\n",
              "      <td>{'street': 'Kadıköy, İstanbul, Turkey', 'subur...</td>\n",
              "      <td>{'availability_30': 27, 'availability_60': 57,...</td>\n",
              "      <td>{'review_scores_accuracy': 10, 'review_scores_...</td>\n",
              "      <td>[{'_id': '68162172', 'date': 2016-04-02 04:00:...</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>[0.023723349, 0.0064210771, -0.0339970738, -0....</td>\n",
              "      <td>[-0.1006749049, 0.4022984803, -0.1821258366, 0...</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>5 rows × 43 columns</p>\n",
              "</div>\n",
              "    <div class=\"colab-df-buttons\">\n",
              "\n",
              "  <div class=\"colab-df-container\">\n",
              "    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-4b3fa277-0477-41c7-8196-d88c7b195e03')\"\n",
              "            title=\"Convert this dataframe to an interactive table.\"\n",
              "            style=\"display:none;\">\n",
              "\n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
              "    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
              "  </svg>\n",
              "    </button>\n",
              "\n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    .colab-df-buttons div {\n",
              "      margin-bottom: 4px;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "    <script>\n",
              "      const buttonEl =\n",
              "        document.querySelector('#df-4b3fa277-0477-41c7-8196-d88c7b195e03 button.colab-df-convert');\n",
              "      buttonEl.style.display =\n",
              "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "      async function convertToInteractive(key) {\n",
              "        const element = document.querySelector('#df-4b3fa277-0477-41c7-8196-d88c7b195e03');\n",
              "        const dataTable =\n",
              "          await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                    [key], {});\n",
              "        if (!dataTable) return;\n",
              "\n",
              "        const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "          '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "          + ' to learn more about interactive tables.';\n",
              "        element.innerHTML = '';\n",
              "        dataTable['output_type'] = 'display_data';\n",
              "        await google.colab.output.renderOutput(dataTable, element);\n",
              "        const docLink = document.createElement('div');\n",
              "        docLink.innerHTML = docLinkHtml;\n",
              "        element.appendChild(docLink);\n",
              "      }\n",
              "    </script>\n",
              "  </div>\n",
              "\n",
              "\n",
              "<div id=\"df-6213bf49-1579-4ab9-88a8-3c8deaee255f\">\n",
              "  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-6213bf49-1579-4ab9-88a8-3c8deaee255f')\"\n",
              "            title=\"Suggest charts\"\n",
              "            style=\"display:none;\">\n",
              "\n",
              "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "     width=\"24px\">\n",
              "    <g>\n",
              "        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n",
              "    </g>\n",
              "</svg>\n",
              "  </button>\n",
              "\n",
              "<style>\n",
              "  .colab-df-quickchart {\n",
              "      --bg-color: #E8F0FE;\n",
              "      --fill-color: #1967D2;\n",
              "      --hover-bg-color: #E2EBFA;\n",
              "      --hover-fill-color: #174EA6;\n",
              "      --disabled-fill-color: #AAA;\n",
              "      --disabled-bg-color: #DDD;\n",
              "  }\n",
              "\n",
              "  [theme=dark] .colab-df-quickchart {\n",
              "      --bg-color: #3B4455;\n",
              "      --fill-color: #D2E3FC;\n",
              "      --hover-bg-color: #434B5C;\n",
              "      --hover-fill-color: #FFFFFF;\n",
              "      --disabled-bg-color: #3B4455;\n",
              "      --disabled-fill-color: #666;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart {\n",
              "    background-color: var(--bg-color);\n",
              "    border: none;\n",
              "    border-radius: 50%;\n",
              "    cursor: pointer;\n",
              "    display: none;\n",
              "    fill: var(--fill-color);\n",
              "    height: 32px;\n",
              "    padding: 0;\n",
              "    width: 32px;\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart:hover {\n",
              "    background-color: var(--hover-bg-color);\n",
              "    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "    fill: var(--button-hover-fill-color);\n",
              "  }\n",
              "\n",
              "  .colab-df-quickchart-complete:disabled,\n",
              "  .colab-df-quickchart-complete:disabled:hover {\n",
              "    background-color: var(--disabled-bg-color);\n",
              "    fill: var(--disabled-fill-color);\n",
              "    box-shadow: none;\n",
              "  }\n",
              "\n",
              "  .colab-df-spinner {\n",
              "    border: 2px solid var(--fill-color);\n",
              "    border-color: transparent;\n",
              "    border-bottom-color: var(--fill-color);\n",
              "    animation:\n",
              "      spin 1s steps(1) infinite;\n",
              "  }\n",
              "\n",
              "  @keyframes spin {\n",
              "    0% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "      border-left-color: var(--fill-color);\n",
              "    }\n",
              "    20% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    30% {\n",
              "      border-color: transparent;\n",
              "      border-left-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    40% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-top-color: var(--fill-color);\n",
              "    }\n",
              "    60% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "    }\n",
              "    80% {\n",
              "      border-color: transparent;\n",
              "      border-right-color: var(--fill-color);\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "    90% {\n",
              "      border-color: transparent;\n",
              "      border-bottom-color: var(--fill-color);\n",
              "    }\n",
              "  }\n",
              "</style>\n",
              "\n",
              "  <script>\n",
              "    async function quickchart(key) {\n",
              "      const quickchartButtonEl =\n",
              "        document.querySelector('#' + key + ' button');\n",
              "      quickchartButtonEl.disabled = true;  // To prevent multiple clicks.\n",
              "      quickchartButtonEl.classList.add('colab-df-spinner');\n",
              "      try {\n",
              "        const charts = await google.colab.kernel.invokeFunction(\n",
              "            'suggestCharts', [key], {});\n",
              "      } catch (error) {\n",
              "        console.error('Error during call to suggestCharts:', error);\n",
              "      }\n",
              "      quickchartButtonEl.classList.remove('colab-df-spinner');\n",
              "      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n",
              "    }\n",
              "    (() => {\n",
              "      let quickchartButtonEl =\n",
              "        document.querySelector('#df-6213bf49-1579-4ab9-88a8-3c8deaee255f button');\n",
              "      quickchartButtonEl.style.display =\n",
              "        google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "    })();\n",
              "  </script>\n",
              "</div>\n",
              "\n",
              "    </div>\n",
              "  </div>\n"
            ],
            "text/plain": [
              "        _id                            listing_url  \\\n",
              "0  10006546  https://www.airbnb.com/rooms/10006546   \n",
              "1  10021707  https://www.airbnb.com/rooms/10021707   \n",
              "2   1001265   https://www.airbnb.com/rooms/1001265   \n",
              "3  10009999  https://www.airbnb.com/rooms/10009999   \n",
              "4  10047964  https://www.airbnb.com/rooms/10047964   \n",
              "\n",
              "                               name  \\\n",
              "0           Ribeira Charming Duplex   \n",
              "1          Private Room in Bushwick   \n",
              "2  Ocean View Waikiki Marina w/prkg   \n",
              "3      Horto flat with small garden   \n",
              "4    Charming Flat in Downtown Moda   \n",
              "\n",
              "                                             summary  \\\n",
              "0  Fantastic duplex apartment with three bedrooms...   \n",
              "1  Here exists a very cozy room for rent in a sha...   \n",
              "2  A short distance from Honolulu's billion dolla...   \n",
              "3  One bedroom + sofa-bed in quiet and bucolic ne...   \n",
              "4  Fully furnished 3+1 flat decorated with vintag...   \n",
              "\n",
              "                                               space  \\\n",
              "0  Privileged views of the Douro River and Ribeir...   \n",
              "1                                                      \n",
              "2  Great studio located on Ala Moana across the s...   \n",
              "3  Lovely one bedroom + sofa-bed in the living ro...   \n",
              "4  The apartment is composed of 1 big bedroom wit...   \n",
              "\n",
              "                                         description  \\\n",
              "0  Fantastic duplex apartment with three bedrooms...   \n",
              "1  Here exists a very cozy room for rent in a sha...   \n",
              "2  A short distance from Honolulu's billion dolla...   \n",
              "3  One bedroom + sofa-bed in quiet and bucolic ne...   \n",
              "4  Fully furnished 3+1 flat decorated with vintag...   \n",
              "\n",
              "                               neighborhood_overview  \\\n",
              "0  In the neighborhood of the river, you can find...   \n",
              "1                                                      \n",
              "2             You can breath ocean as well as aloha.   \n",
              "3  This charming ground floor flat is located in ...   \n",
              "4  With its diversity Moda- Kadikoy is one of the...   \n",
              "\n",
              "                                               notes  \\\n",
              "0  Lose yourself in the narrow streets and stairc...   \n",
              "1                                                      \n",
              "2                                                      \n",
              "3  There´s a table in the living room now, that d...   \n",
              "4                                                      \n",
              "\n",
              "                                             transit  \\\n",
              "0  Transport: • Metro station and S. Bento railwa...   \n",
              "1                                                      \n",
              "2  Honolulu does have a very good air conditioned...   \n",
              "3  Easy access to transport (bus, taxi, car) and ...   \n",
              "4                                                      \n",
              "\n",
              "                                              access  ...  \\\n",
              "0  We are always available to help guests. The ho...  ...   \n",
              "1                                                     ...   \n",
              "2                           Pool, hot tub and tennis  ...   \n",
              "3                                                     ...   \n",
              "4                                                     ...   \n",
              "\n",
              "                                              images  \\\n",
              "0  {'thumbnail_url': '', 'medium_url': '', 'pictu...   \n",
              "1  {'thumbnail_url': '', 'medium_url': '', 'pictu...   \n",
              "2  {'thumbnail_url': '', 'medium_url': '', 'pictu...   \n",
              "3  {'thumbnail_url': '', 'medium_url': '', 'pictu...   \n",
              "4  {'thumbnail_url': '', 'medium_url': '', 'pictu...   \n",
              "\n",
              "                                                host  \\\n",
              "0  {'host_id': '51399391', 'host_url': 'https://w...   \n",
              "1  {'host_id': '11275734', 'host_url': 'https://w...   \n",
              "2  {'host_id': '5448114', 'host_url': 'https://ww...   \n",
              "3  {'host_id': '1282196', 'host_url': 'https://ww...   \n",
              "4  {'host_id': '1241644', 'host_url': 'https://ww...   \n",
              "\n",
              "                                             address  \\\n",
              "0  {'street': 'Porto, Porto, Portugal', 'suburb':...   \n",
              "1  {'street': 'Brooklyn, NY, United States', 'sub...   \n",
              "2  {'street': 'Honolulu, HI, United States', 'sub...   \n",
              "3  {'street': 'Rio de Janeiro, Rio de Janeiro, Br...   \n",
              "4  {'street': 'Kadıköy, İstanbul, Turkey', 'subur...   \n",
              "\n",
              "                                        availability  \\\n",
              "0  {'availability_30': 28, 'availability_60': 47,...   \n",
              "1  {'availability_30': 0, 'availability_60': 0, '...   \n",
              "2  {'availability_30': 16, 'availability_60': 46,...   \n",
              "3  {'availability_30': 0, 'availability_60': 0, '...   \n",
              "4  {'availability_30': 27, 'availability_60': 57,...   \n",
              "\n",
              "                                       review_scores  \\\n",
              "0  {'review_scores_accuracy': 9, 'review_scores_c...   \n",
              "1  {'review_scores_accuracy': 10, 'review_scores_...   \n",
              "2  {'review_scores_accuracy': 9, 'review_scores_c...   \n",
              "3  {'review_scores_accuracy': None, 'review_score...   \n",
              "4  {'review_scores_accuracy': 10, 'review_scores_...   \n",
              "\n",
              "                                             reviews  weekly_price  \\\n",
              "0  [{'_id': '58663741', 'date': 2016-01-03 05:00:...           NaN   \n",
              "1  [{'_id': '61050713', 'date': 2016-01-31 05:00:...           NaN   \n",
              "2  [{'_id': '4765259', 'date': 2013-05-24 04:00:0...         650.0   \n",
              "3                                                 []        1492.0   \n",
              "4  [{'_id': '68162172', 'date': 2016-04-02 04:00:...           NaN   \n",
              "\n",
              "  monthly_price                                    text_embeddings  \\\n",
              "0           NaN  [0.0123710884, -0.0180913936, -0.016843712, -0...   \n",
              "1           NaN  [0.0153845912, -0.0348115042, -0.0093448907, 0...   \n",
              "2        2150.0  [-0.0400562622, -0.0405789167, 0.000644172, 0....   \n",
              "3        4849.0  [-0.063234821, 0.0017937823, -0.0243996996, -0...   \n",
              "4           NaN  [0.023723349, 0.0064210771, -0.0339970738, -0....   \n",
              "\n",
              "                                    image_embeddings  \n",
              "0  [-0.1302358955, 0.1534578055, 0.0199299306, -0...  \n",
              "1  [0.0340401195, 0.1742489338, -0.1572628617, 0....  \n",
              "2  [-0.1640156209, 0.1256971657, 0.6594450474, -0...  \n",
              "3  [-0.1292964518, 0.037789464, 0.2443587631, 0.0...  \n",
              "4  [-0.1006749049, 0.4022984803, -0.1821258366, 0...  \n",
              "\n",
              "[5 rows x 43 columns]"
            ]
          },
          "execution_count": 30,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "data_df.head(5)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tlMnDPOfzMK5"
      },
      "source": [
        "## Data Processing"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 31,
      "metadata": {
        "id": "iu3PppUWJjMc"
      },
      "outputs": [],
      "source": [
        "from llama_index.core import Document"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 32,
      "metadata": {
        "id": "4zCDxG4_IiiK"
      },
      "outputs": [],
      "source": [
        "# Convert the DataFrame to dictionary\n",
        "docs = data_df.to_dict(orient=\"records\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 167,
      "metadata": {
        "id": "uyl1ChTXIk9h"
      },
      "outputs": [],
      "source": [
        "llama_documents = []\n",
        "fields_to_include = [\n",
        "    \"amenities\",\n",
        "    \"address\",\n",
        "    \"availability\",\n",
        "    \"review_scores\",\n",
        "    \"listing_url\",\n",
        "]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 168,
      "metadata": {
        "id": "AWpooso1Amft"
      },
      "outputs": [],
      "source": [
        "for doc in docs:\n",
        "    metadata = {key: doc[key] for key in fields_to_include}\n",
        "    llama_doc = Document(text=doc[\"description\"], metadata=metadata)\n",
        "    llama_documents.append(llama_doc)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 169,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "dIeOtRRuJXKi",
        "outputId": "3f8395c6-3cb5-4486-d9f3-c8aa062ea47f"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "Document(id_='54f8e3ba-9624-4ac4-986a-e19d67a89e7c', embedding=None, metadata={'amenities': ['TV', 'Cable TV', 'Wifi', 'Kitchen', 'Paid parking off premises', 'Smoking allowed', 'Pets allowed', 'Buzzer/wireless intercom', 'Heating', 'Family/kid friendly', 'Washer', 'First aid kit', 'Fire extinguisher', 'Essentials', 'Hangers', 'Hair dryer', 'Iron', 'Pack ’n Play/travel crib', 'Room-darkening shades', 'Hot water', 'Bed linens', 'Extra pillows and blankets', 'Microwave', 'Coffee maker', 'Refrigerator', 'Dishwasher', 'Dishes and silverware', 'Cooking basics', 'Oven', 'Stove', 'Cleaning before checkout', 'Waterfront'], 'address': {'street': 'Porto, Porto, Portugal', 'suburb': '', 'government_area': 'Cedofeita, Ildefonso, Sé, Miragaia, Nicolau, Vitória', 'market': 'Porto', 'country': 'Portugal', 'country_code': 'PT', 'location': {'type': 'Point', 'coordinates': [-8.61308, 41.1413], 'is_location_exact': False}}, 'availability': {'availability_30': 28, 'availability_60': 47, 'availability_90': 74, 'availability_365': 239}, 'review_scores': {'review_scores_accuracy': 9, 'review_scores_cleanliness': 9, 'review_scores_checkin': 10, 'review_scores_communication': 10, 'review_scores_location': 10, 'review_scores_value': 9, 'review_scores_rating': 89}, 'listing_url': 'https://www.airbnb.com/rooms/10006546'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, text='Fantastic duplex apartment with three bedrooms, located in the historic area of Porto, Ribeira (Cube) - UNESCO World Heritage Site. Centenary building fully rehabilitated, without losing their original character. Privileged views of the Douro River and Ribeira square, our apartment offers the perfect conditions to discover the history and the charm of Porto. Apartment comfortable, charming, romantic and cozy in the heart of Ribeira. Within walking distance of all the most emblematic places of the city of Porto. The apartment is fully equipped to host 8 people, with cooker, oven, washing machine, dishwasher, microwave, coffee machine (Nespresso) and kettle. The apartment is located in a very typical area of the city that allows to cross with the most picturesque population of the city, welcoming, genuine and happy people that fills the streets with his outspoken speech and contagious with your sincere generosity, wrapped in a only parochial spirit. We are always available to help guests', mimetype='text/plain', start_char_idx=None, end_char_idx=None, text_template='{metadata_str}\\n\\n{content}', metadata_template='{key}: {value}', metadata_seperator='\\n')"
            ]
          },
          "execution_count": 169,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "llama_documents[0]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dC7CDZGhzPLn"
      },
      "source": [
        "## Create MongoDB Atlas Vector Store"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 186,
      "metadata": {
        "id": "HCVyW9xGKrF3"
      },
      "outputs": [],
      "source": [
        "from llama_index.core import StorageContext, VectorStoreIndex\n",
        "from llama_index.vector_stores.mongodb import MongoDBAtlasVectorSearch\n",
        "from pymongo.errors import OperationFailure"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 187,
      "metadata": {
        "id": "iCqflLPNBZe4"
      },
      "outputs": [],
      "source": [
        "DB_NAME = \"airbnb\"\n",
        "COLLECTION_NAME = \"listings_reviews\"\n",
        "VS_INDEX_NAME = \"vector_index\"\n",
        "FTS_INDEX_NAME = \"fts_index\"\n",
        "collection = mongodb_client[DB_NAME][COLLECTION_NAME]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 189,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 81,
          "referenced_widgets": [
            "435f2a6981e64882b94cbe137eadddde",
            "fce1edc87223443bb9dce94d9cd930bc",
            "9ffc973f8c8844c59c1c999746bc87b9",
            "225f2955a7314e949f4d1fc90e0fdcb8",
            "f4a60ad3051942e7b1c68a8364c300e7",
            "75ca100699444d04ae5c03d027473886",
            "cfae9079f4e64e7a8798619a3aa9b4cc",
            "b5e34cde4278413d977193885a74149c",
            "786458928ada491eb2c9468f422b85fb",
            "2add43683c5b4dfab0b7224bb0a4b71c",
            "f61a6afef1d646afa11d57b57e7d573a",
            "6f0165eb239e4c11bd7aff65f79b1a6b",
            "975f53abc78e49088fba9a825663d91f",
            "bc7980ba565f42d4bfdeeae6bf427daa",
            "d101bd0c5ddd44ee91e94cb2c6df33a8",
            "96e691ddb8b1472d850fe09b862101bb",
            "3a4035af32374d9f8163bd19d13504fa",
            "406fbc51c11344998647f5ee66901fc4",
            "e0c0df23ca744bc6a123bb31b6c17915",
            "d3eacb1dd8cf4d5aa85592c5806a5821",
            "9a9ba8090fb74458848eeb0ea7ecea17",
            "53be48022b114167ae066632ccfdd480"
          ]
        },
        "id": "D5sne8YMBa80",
        "outputId": "38fa666c-99ed-4ff0-8f10-c7f94da8c48d"
      },
      "outputs": [
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "435f2a6981e64882b94cbe137eadddde",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "Parsing nodes:   0%|          | 0/200 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "6f0165eb239e4c11bd7aff65f79b1a6b",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "Generating embeddings:   0%|          | 0/200 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "vector_store = MongoDBAtlasVectorSearch(\n",
        "    mongodb_client,\n",
        "    db_name=DB_NAME,\n",
        "    collection_name=COLLECTION_NAME,\n",
        "    vector_index_name=VS_INDEX_NAME,\n",
        "    fulltext_index_name=FTS_INDEX_NAME,\n",
        "    embedding_key=\"embedding\",\n",
        "    text_key=\"text\",\n",
        ")\n",
        "vector_store_context = StorageContext.from_defaults(vector_store=vector_store)\n",
        "vector_store_index = VectorStoreIndex.from_documents(\n",
        "    llama_documents, storage_context=vector_store_context, show_progress=True\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HGL7X16WzaUJ"
      },
      "source": [
        "## Create Vector and Full-text Search Indexes"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 190,
      "metadata": {
        "id": "1LT33uW8MDUs"
      },
      "outputs": [],
      "source": [
        "from pymongo.operations import SearchIndexModel"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 191,
      "metadata": {
        "id": "44MagrRJL3Pm"
      },
      "outputs": [],
      "source": [
        "vs_model = SearchIndexModel(\n",
        "    definition={\n",
        "        \"fields\": [\n",
        "            {\n",
        "                \"type\": \"vector\",\n",
        "                \"path\": \"embedding\",\n",
        "                \"numDimensions\": 256,\n",
        "                \"similarity\": \"cosine\",\n",
        "            },\n",
        "            {\"type\": \"filter\", \"path\": \"metadata.amenities\"},\n",
        "            {\"type\": \"filter\", \"path\": \"metadata.review_scores.review_scores_rating\"},\n",
        "        ]\n",
        "    },\n",
        "    name=VS_INDEX_NAME,\n",
        "    type=\"vectorSearch\",\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 192,
      "metadata": {
        "id": "w7EFnGlYMGpI"
      },
      "outputs": [],
      "source": [
        "fts_model = SearchIndexModel(\n",
        "    definition={\"mappings\": {\"dynamic\": False, \"fields\": {\"text\": {\"type\": \"string\"}}}},\n",
        "    name=FTS_INDEX_NAME,\n",
        "    type=\"search\",\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 193,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Mwtj-l7YMKRv",
        "outputId": "d27099f3-947a-4f80-c235-0e95d0c54345"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Successfully created index for model <pymongo.operations.SearchIndexModel object at 0x7ea847d36380>.\n",
            "Successfully created index for model <pymongo.operations.SearchIndexModel object at 0x7ea847f32170>.\n"
          ]
        }
      ],
      "source": [
        "for model in [vs_model, fts_model]:\n",
        "    try:\n",
        "        collection.create_search_index(model=model)\n",
        "        print(f\"Successfully created index for model {model}.\")\n",
        "    except OperationFailure:\n",
        "        print(f\"Duplicate index found for model {model}. Skipping index creation.\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ZqjMKHMizlOM"
      },
      "source": [
        "## Creating Retriever Tool for the Agent"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 194,
      "metadata": {
        "id": "tHvIkj-UM72t"
      },
      "outputs": [],
      "source": [
        "from typing import List\n",
        "\n",
        "from llama_index.core.tools import FunctionTool\n",
        "from llama_index.core.vector_stores import (\n",
        "    FilterCondition,\n",
        "    FilterOperator,\n",
        "    MetadataFilter,\n",
        "    MetadataFilters,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 195,
      "metadata": {
        "id": "XVz-iQDFRwnH"
      },
      "outputs": [],
      "source": [
        "def get_airbnb_listings(query: str, amenities: List[str]) -> str:\n",
        "    \"\"\"\n",
        "    Provides information about Airbnb listings.\n",
        "\n",
        "    query (str): User query\n",
        "    amenities (List[str]): List of amenities\n",
        "    rating (int): Listing rating\n",
        "    \"\"\"\n",
        "    filters = [\n",
        "        MetadataFilter(\n",
        "            key=\"metadata.review_scores.review_scores_rating\",\n",
        "            value=80,\n",
        "            operator=FilterOperator.GTE,\n",
        "        )\n",
        "    ]\n",
        "    amenities_filter = [\n",
        "        MetadataFilter(\n",
        "            key=\"metadata.amenities\", value=amenity, operator=FilterOperator.EQ\n",
        "        )\n",
        "        for amenity in amenities\n",
        "    ]\n",
        "    filters.extend(amenities_filter)\n",
        "\n",
        "    filters = MetadataFilters(\n",
        "        filters=filters,\n",
        "        condition=FilterCondition.AND,\n",
        "    )\n",
        "\n",
        "    query_engine = vector_store_index.as_query_engine(\n",
        "        similarity_top_k=5, vector_store_query_mode=\"hybrid\", alpha=0.7, filters=filters\n",
        "    )\n",
        "    response = query_engine.query(query)\n",
        "    nodes = response.source_nodes\n",
        "    listings = [node.metadata[\"listing_url\"] for node in nodes]\n",
        "    return listings"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 196,
      "metadata": {
        "id": "-89_2_OXTuz9"
      },
      "outputs": [],
      "source": [
        "query_tool = FunctionTool.from_defaults(\n",
        "    name=\"get_airbnb_listings\", fn=get_airbnb_listings\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GyCMYLAB1ifQ"
      },
      "source": [
        "## Create the AI Agent"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 197,
      "metadata": {
        "id": "13WPPB5RPR1o"
      },
      "outputs": [],
      "source": [
        "from llama_index.core.agent import AgentRunner, FunctionCallingAgentWorker"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 198,
      "metadata": {
        "id": "3JKQeSbePU-3"
      },
      "outputs": [],
      "source": [
        "agent_worker = FunctionCallingAgentWorker.from_tools(\n",
        "    [query_tool], llm=llm, verbose=True\n",
        ")\n",
        "agent = AgentRunner(agent_worker)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 199,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "f0PVXC07PoCx",
        "outputId": "7f4f27bb-5a5c-430e-9004-228482ca4fa8"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Added user message to memory: Give me listings in Porto with a Waterfront.\n",
            "=== Calling Function ===\n",
            "Calling function: get_airbnb_listings with args: {\"query\": \"Porto\", \"amenities\": [\"Waterfront\"]}\n",
            "=== Function Output ===\n",
            "['https://www.airbnb.com/rooms/10006546', 'https://www.airbnb.com/rooms/11207193']\n",
            "=== LLM Response ===\n",
            "Here are some Airbnb listings in Porto with a waterfront:\n",
            "\n",
            "1. [Listing 1](https://www.airbnb.com/rooms/10006546)\n",
            "2. [Listing 2](https://www.airbnb.com/rooms/11207193)\n"
          ]
        }
      ],
      "source": [
        "response = agent.query(\"Give me listings in Porto with a Waterfront.\")"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "225f2955a7314e949f4d1fc90e0fdcb8": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_2add43683c5b4dfab0b7224bb0a4b71c",
            "placeholder": "​",
            "style": "IPY_MODEL_f61a6afef1d646afa11d57b57e7d573a",
            "value": " 200/200 [00:00&lt;00:00, 897.87it/s]"
          }
        },
        "2add43683c5b4dfab0b7224bb0a4b71c": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "3a4035af32374d9f8163bd19d13504fa": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "406fbc51c11344998647f5ee66901fc4": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "435f2a6981e64882b94cbe137eadddde": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HBoxModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_fce1edc87223443bb9dce94d9cd930bc",
              "IPY_MODEL_9ffc973f8c8844c59c1c999746bc87b9",
              "IPY_MODEL_225f2955a7314e949f4d1fc90e0fdcb8"
            ],
            "layout": "IPY_MODEL_f4a60ad3051942e7b1c68a8364c300e7"
          }
        },
        "53be48022b114167ae066632ccfdd480": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "6f0165eb239e4c11bd7aff65f79b1a6b": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HBoxModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_975f53abc78e49088fba9a825663d91f",
              "IPY_MODEL_bc7980ba565f42d4bfdeeae6bf427daa",
              "IPY_MODEL_d101bd0c5ddd44ee91e94cb2c6df33a8"
            ],
            "layout": "IPY_MODEL_96e691ddb8b1472d850fe09b862101bb"
          }
        },
        "75ca100699444d04ae5c03d027473886": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "786458928ada491eb2c9468f422b85fb": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "ProgressStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "96e691ddb8b1472d850fe09b862101bb": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "975f53abc78e49088fba9a825663d91f": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_3a4035af32374d9f8163bd19d13504fa",
            "placeholder": "​",
            "style": "IPY_MODEL_406fbc51c11344998647f5ee66901fc4",
            "value": "Generating embeddings: 100%"
          }
        },
        "9a9ba8090fb74458848eeb0ea7ecea17": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "9ffc973f8c8844c59c1c999746bc87b9": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "FloatProgressModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_b5e34cde4278413d977193885a74149c",
            "max": 200,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_786458928ada491eb2c9468f422b85fb",
            "value": 200
          }
        },
        "b5e34cde4278413d977193885a74149c": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "bc7980ba565f42d4bfdeeae6bf427daa": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "FloatProgressModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_e0c0df23ca744bc6a123bb31b6c17915",
            "max": 200,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_d3eacb1dd8cf4d5aa85592c5806a5821",
            "value": 200
          }
        },
        "cfae9079f4e64e7a8798619a3aa9b4cc": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "d101bd0c5ddd44ee91e94cb2c6df33a8": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_9a9ba8090fb74458848eeb0ea7ecea17",
            "placeholder": "​",
            "style": "IPY_MODEL_53be48022b114167ae066632ccfdd480",
            "value": " 200/200 [00:07&lt;00:00, 28.69it/s]"
          }
        },
        "d3eacb1dd8cf4d5aa85592c5806a5821": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "ProgressStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "e0c0df23ca744bc6a123bb31b6c17915": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "f4a60ad3051942e7b1c68a8364c300e7": {
          "model_module": "@jupyter-widgets/base",
          "model_module_version": "1.2.0",
          "model_name": "LayoutModel",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "f61a6afef1d646afa11d57b57e7d573a": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "DescriptionStyleModel",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "fce1edc87223443bb9dce94d9cd930bc": {
          "model_module": "@jupyter-widgets/controls",
          "model_module_version": "1.5.0",
          "model_name": "HTMLModel",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_75ca100699444d04ae5c03d027473886",
            "placeholder": "​",
            "style": "IPY_MODEL_cfae9079f4e64e7a8798619a3aa9b4cc",
            "value": "Parsing nodes: 100%"
          }
        },
        "state": {}
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
